package com.jl15988.simpletools.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jl15988.simpletools.appcore.entity.App;
import com.jl15988.simpletools.appcore.mapper.AppMapper;
import com.jl15988.simpletools.appcore.service.AuditService;
import com.jl15988.simpletools.common.exception.BusinessException;
import com.jl15988.simpletools.system.domain.entity.User;
import com.jl15988.simpletools.system.mapper.UserMapper;
import com.jl15988.simpletools.system.service.DashboardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 仪表盘服务实现类
 *
 * @author jl15988
 */
@Slf4j
@Service
public class DashboardServiceImpl implements DashboardService {

    @Autowired
    private AppMapper appMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AuditService auditService;

    @Override
    public Map<String, Object> getDashboardData() {
        Map<String, Object> result = new HashMap<>(8);

        // 获取应用总数
        long totalApps = appMapper.selectCount(null);
        result.put("totalApps", totalApps);

        // 获取昨日新增应用数
        LocalDateTime yesterday = LocalDate.now().minusDays(1).atStartOfDay();
        LocalDateTime today = LocalDate.now().atStartOfDay();
        long appIncrease = appMapper.selectCount(new LambdaQueryWrapper<App>()
                .between(App::getCreatedAt, yesterday, today));
        result.put("appIncrease", appIncrease);

        // 获取用户总数
        long totalUsers = userMapper.selectCount(null);
        result.put("totalUsers", totalUsers);

        // 获取昨日新增用户数
        long userIncrease = userMapper.selectCount(new LambdaQueryWrapper<User>()
                .between(User::getCreatedAt, yesterday, today));
        result.put("userIncrease", userIncrease);

        // 获取下载总数
        long totalDownloads = appMapper.selectTotalDownloads();
        result.put("totalDownloads", totalDownloads);

        // 获取昨日新增下载数
        long downloadIncrease = appMapper.selectDownloadsByDateRange(yesterday, today);
        result.put("downloadIncrease", downloadIncrease);

        // 获取待审核应用数
        long pendingAudits = auditService.getPendingAuditCount();
        result.put("pendingAudits", pendingAudits);

        // 获取热门应用排行
        List<Map<String, Object>> topApps = appMapper.selectTopAppsByDownloads(10);
        result.put("topApps", topApps);

        return result;
    }

    @Override
    public List<Map<String, Object>> getDownloadTrend(String timeRange) {
        LocalDateTime startDate;
        LocalDateTime endDate = LocalDateTime.now();
        DateTimeFormatter formatter;

        switch (timeRange) {
            case "week":
                // 本周的第一天
                startDate = LocalDate.now().with(WeekFields.of(Locale.getDefault()).dayOfWeek(), 1).atStartOfDay();
                formatter = DateTimeFormatter.ofPattern("E"); // 星期几
                break;
            case "month":
                // 本月的第一天
                startDate = LocalDate.now().withDayOfMonth(1).atStartOfDay();
                formatter = DateTimeFormatter.ofPattern("dd"); // 日期
                break;
            case "year":
                // 本年的第一天
                startDate = LocalDate.now().with(TemporalAdjusters.firstDayOfYear()).atStartOfDay();
                formatter = DateTimeFormatter.ofPattern("MM"); // 月份
                break;
            default:
                throw new BusinessException("无效的时间范围");
        }

        // 获取下载趋势数据
        List<Map<String, Object>> downloadTrend = appMapper.selectDownloadTrend(startDate, endDate, timeRange);

        // 如果数据不完整，填充缺失的日期
        return fillMissingDates(downloadTrend, startDate, endDate, formatter, timeRange);
    }

    /**
     * 填充缺失的日期数据
     *
     * @param data       原始数据
     * @param startDate  开始日期
     * @param endDate    结束日期
     * @param formatter  日期格式化器
     * @param timeRange  时间范围
     * @return 填充后的数据
     */
    private List<Map<String, Object>> fillMissingDates(List<Map<String, Object>> data, LocalDateTime startDate,
                                                      LocalDateTime endDate, DateTimeFormatter formatter, String timeRange) {
        // 将原始数据转换为Map，以日期为键
        Map<String, Long> dataMap = data.stream()
                .collect(Collectors.toMap(
                        item -> (String) item.get("date"),
                        item -> (Long) item.get("count")
                ));

        List<Map<String, Object>> result = new ArrayList<>();
        LocalDate current = startDate.toLocalDate();
        LocalDate end = endDate.toLocalDate();

        while (!current.isAfter(end)) {
            String dateStr = current.format(formatter);
            long count = dataMap.getOrDefault(dateStr, 0L);

            Map<String, Object> item = new HashMap<>(2);
            item.put("date", dateStr);
            item.put("count", count);
            result.add(item);

            // 根据时间范围增加日期
            switch (timeRange) {
                case "week":
                    current = current.plusDays(1);
                    break;
                case "month":
                    current = current.plusDays(1);
                    break;
                case "year":
                    current = current.plusMonths(1);
                    break;
            }
        }

        return result;
    }
} 